save/restore: Batch contiguous page-sized writes together during domain save.
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 9 Apr 2008 14:19:09 +0000 (15:19 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 9 Apr 2008 14:19:09 +0000 (15:19 +0100)
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
tools/libxc/xc_domain_save.c

index 34f554cb905d18a657d80f6e7caa15a8d5e821eb..ed46421c286ac93830159b824ce637b0ecf716b4 100644 (file)
@@ -1048,7 +1048,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
     /* Now write out each data page, canonicalising page tables as we go... */
     for ( ; ; )
     {
-        unsigned int prev_pc, sent_this_iter, N, batch;
+        unsigned int prev_pc, sent_this_iter, N, batch, run;
 
         iter++;
         sent_this_iter = 0;
@@ -1225,6 +1225,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
             }
 
             /* entering this loop, pfn_type is now in pfns (Not mfns) */
+            run = 0;
             for ( j = 0; j < batch; j++ )
             {
                 unsigned long pfn, pagetype;
@@ -1233,7 +1234,25 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
                 pfn      = pfn_type[j] & ~XEN_DOMCTL_PFINFO_LTAB_MASK;
                 pagetype = pfn_type[j] &  XEN_DOMCTL_PFINFO_LTAB_MASK;
 
-                /* write out pages in batch */
+                if ( pagetype != 0 )
+                {
+                    /* If the page is not a normal data page, write out any
+                       run of pages we may have previously acumulated */
+                    if ( run )
+                    {
+                        if ( ratewrite(io_fd, live, 
+                                       (char*)region_base+(PAGE_SIZE*(j-run)), 
+                                       PAGE_SIZE*run) != PAGE_SIZE*run )
+                        {
+                            ERROR("Error when writing to state file (4a)"
+                                  " (errno %d)", errno);
+                            goto out;
+                        }                        
+                        run = 0;
+                    }
+                }
+
+                /* skip pages that aren't present */
                 if ( pagetype == XEN_DOMCTL_PFINFO_XTAB )
                     continue;
 
@@ -1255,24 +1274,31 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 
                     if ( ratewrite(io_fd, live, page, PAGE_SIZE) != PAGE_SIZE )
                     {
-                        ERROR("Error when writing to state file (4)"
+                        ERROR("Error when writing to state file (4b)"
                               " (errno %d)", errno);
                         goto out;
                     }
                 }
                 else
                 {
-                    /* We have a normal page: just write it directly. */
-                    if ( ratewrite(io_fd, live, spage, PAGE_SIZE) !=
-                         PAGE_SIZE )
-                    {
-                        ERROR("Error when writing to state file (5)"
-                              " (errno %d)", errno);
-                        goto out;
-                    }
+                    /* We have a normal page: accumulate it for writing. */
+                    run++;
                 }
             } /* end of the write out for this batch */
 
+            if ( run )
+            {
+                /* write out the last accumulated run of pages */
+                if ( ratewrite(io_fd, live, 
+                               (char*)region_base+(PAGE_SIZE*(j-run)), 
+                               PAGE_SIZE*run) != PAGE_SIZE*run )
+                {
+                    ERROR("Error when writing to state file (4c)"
+                          " (errno %d)", errno);
+                    goto out;
+                }                        
+            }
+
             sent_this_iter += batch;
 
             munmap(region_base, batch*PAGE_SIZE);